package com.arcbees.test.collaborative.client;

import java.util.HashSet;
import java.util.Set;

import com.arcbees.test.collaborative.server.diffsync.ServerDiffMatchPatch;
import com.arcbees.test.collaborative.shared.diffsync.DiffHandler;
import com.arcbees.test.collaborative.shared.diffsync.DocumentShadow;
import com.arcbees.test.collaborative.shared.diffsync.Edits;
import com.arcbees.test.collaborative.shared.diffsync.PatchResult;

public class FakeServer {

  class FakeServerClient {
    FakeClient client;
    DocumentShadow documentShadow;

    public FakeServerClient(FakeClient client) {
      this.client = client;
      documentShadow = null;// new ServerDocumentShadowImpl(diffHandler);
    }
  }

  private Set<FakeServerClient> clients;
  private DiffHandler diffHandler;
  private String serverText;

  public FakeServer() {
    this.diffHandler = new DiffHandler(new ServerDiffMatchPatch());
    clients = new HashSet<FakeServerClient>();
    serverText = "";
  }

  public void receiveEdits(FakeClient client, Edits edits) {
    FakeServerClient fakeClient = getClient(client);
    if (edits.hasEdits()) {
      fakeClient.documentShadow.applyEdits(edits);
      PatchResult result = diffHandler.applyEdits(edits, serverText);
      serverText = result.getNewText();
    }
    Edits clientEdits = diffHandler.getEdits(fakeClient.documentShadow,
        serverText);
    if (clientEdits.hasEdits()) {
      fakeClient.documentShadow.updateText(serverText);
    }

    fakeClient.client.receiveEdits(clientEdits);
  }

  private FakeServerClient getClient(FakeClient client) {
    for (FakeServerClient fsc : clients) {
      if (fsc.client.equals(client)) {
        return fsc;
      }
    }

    return null;
  }

  public void subscribe(FakeClient client) {
    clients.add(new FakeServerClient(client));
  }

  // private void notifyClients(FakeServerClient source) {
  // Edits clientEdits;
  // for (FakeServerClient client : clients) {
  // if (!client.equals(source)) {
  // clientEdits = diffHandler.getEdits(client.documentShadow, serverText);
  // client.client.receiveEdits(clientEdits);
  // client.documentShadow.updateText(newText)
  // }
  // }
  // }

  public String getText() {
    return serverText;
  }
}
